﻿using AutoMapper;
using Compass.Wasm.Server.Services.Identities;
using Compass.Wasm.Shared;
using Compass.Wasm.Shared.Wms;
using Compass.WmsService.Domain;
using Compass.WmsService.Domain.Entities;
using Compass.WmsService.Infrastructure;

namespace Compass.Wasm.Server.Services.Wms;
public interface IStockInService : IBaseService<StockInDto>
{
    Task<ApiResponse<IEnumerable<StockInDto>>> GetFromLastByCargoAsync(Guid cargoId,DateTime last);
    Task<ApiResponse<IEnumerable<StockInDto>>> GetAllByCargoAsync(Guid cargoId);
    Task<ApiResponse<IEnumerable<StockInDto>>> GetAllByPeriodAsync(DateTime start, DateTime end);
}
public class StockInService : IStockInService
{
    #region ctor
    private readonly WmsDbContext _dbContext;
    private readonly IWmsRepository _repository;
    private readonly IMapper _mapper;
    private readonly IUserService _userService;
    public StockInService(WmsDbContext dbContext, IWmsRepository repository, IMapper mapper, IUserService userService)
    {
        _dbContext = dbContext;
        _repository = repository;
        _mapper = mapper;
        _userService = userService;
    }
    #endregion

    #region 基本增删改查
    public async Task<ApiResponse<IEnumerable<StockInDto>>> GetAllAsync()
    {
        try
        {
            var models = await _repository.GetStockInsAsync();
            //按照入库时间
            var dtos = await _mapper.ProjectTo<StockInDto>(models).OrderBy(x => x.InTime).ToListAsync();
            //查询物料信息
            foreach (var dto in dtos)
            {
                var cargo = await _repository.GetCargoByIdAsync(dto.CargoId);
                if (cargo==null) continue;
                dto.MtlNumber = cargo.MtlNumber;
                dto.Description = cargo.Description;
                dto.Unit=cargo.Unit;
                dto.Location = cargo.Location;
                dto.Operator= (await _userService.GetSingleAsync(dto.OperatorId)).Result.UserName;
            }
            return new ApiResponse<IEnumerable<StockInDto>> { Status = true, Result = dtos };
        }
        catch (Exception e)
        {
            return new ApiResponse<IEnumerable<StockInDto>> { Status = false, Message = e.Message };
        }
    }

    public async Task<ApiResponse<StockInDto>> GetSingleAsync(Guid id)
    {
        try
        {
            var model = await _repository.GetStockInByIdAsync(id);
            if (model == null) return new ApiResponse<StockInDto> { Status = false, Message = "查询数据失败" };
            var dto = _mapper.Map<StockInDto>(model);

            var cargo = await _repository.GetCargoByIdAsync(dto.CargoId);
            if (cargo!=null)
            {
                dto.MtlNumber = cargo.MtlNumber;
                dto.Description = cargo.Description;
                dto.Unit = cargo.Unit;
                dto.Location = cargo.Location;
                dto.Operator = (await _userService.GetSingleAsync(dto.OperatorId)).Result.UserName;
            }

            return new ApiResponse<StockInDto> { Status = true, Result = dto };
        }
        catch (Exception e)
        {
            return new ApiResponse<StockInDto> { Status = false, Message = e.Message };
        }
    }

    public async Task<ApiResponse<StockInDto>> AddAsync(StockInDto dto)
    {
        try
        {
            var model = new StockIn(Guid.NewGuid(), dto.CargoId, dto.PoNumber,dto.VendorNumber,dto.Price,dto.TransitQuantity,dto.Quantity, dto.ExpectedTime, dto.InTime, dto.OperatorId, dto.Remarks);
            await _dbContext.StockIns.AddAsync(model);
            dto.Id = model.Id;
            return new ApiResponse<StockInDto> { Status = true, Result = dto };
        }
        catch (Exception e)
        {
            return new ApiResponse<StockInDto> { Status = false, Message = e.Message };
        }
    }

    public async Task<ApiResponse<StockInDto>> UpdateAsync(Guid id, StockInDto dto)
    {
        try
        {
            var model = await _repository.GetStockInByIdAsync(id);
            if (model == null) return new ApiResponse<StockInDto> { Status = false, Message = "更新数据失败" };
            model.Update(dto);
            return new ApiResponse<StockInDto> { Status = true, Result = dto };
        }
        catch (Exception e)
        {
            return new ApiResponse<StockInDto> { Status = false, Message = e.Message };
        }
    }

    public async Task<ApiResponse<StockInDto>> DeleteAsync(Guid id)
    {
        try
        {
            var model = await _repository.GetStockInByIdAsync(id);
            if (model == null) return new ApiResponse<StockInDto> { Status = false, Message = "删除数据失败" };
            model.SoftDelete();//软删除
            return new ApiResponse<StockInDto> { Status = true };
        }
        catch (Exception e)
        {
            return new ApiResponse<StockInDto> { Status = false, Message = e.Message };
        }
    }
    #endregion

    #region 扩展查询方法
    public async Task<ApiResponse<IEnumerable<StockInDto>>> GetFromLastByCargoAsync(Guid cargoId,DateTime last)
    {
        try
        {
            var models = await _repository.GetStockInsFromLastByCargoAsync(cargoId,last);
            //按照库位排序
            var dtos = await _mapper.ProjectTo<StockInDto>(models).OrderBy(x => x.InTime).ToListAsync();
            //查询物料信息
            foreach (var dto in dtos)
            {
                var cargo = await _repository.GetCargoByIdAsync(dto.CargoId);
                if (cargo==null) continue;
                dto.MtlNumber = cargo.MtlNumber;
                dto.Description = cargo.Description;
                dto.Unit=cargo.Unit;
                dto.Location = cargo.Location;
                dto.Operator= (await _userService.GetSingleAsync(dto.OperatorId)).Result.UserName;
            }
            return new ApiResponse<IEnumerable<StockInDto>> { Status = true, Result = dtos };
        }
        catch (Exception e)
        {
            return new ApiResponse<IEnumerable<StockInDto>> { Status = false, Message = e.Message };
        }
    }

    public async Task<ApiResponse<IEnumerable<StockInDto>>> GetAllByCargoAsync(Guid cargoId)
    {
        try
        {
            var models = await _repository.GetStockInsByCargoAsync(cargoId);
            //按照库位排序
            var dtos = await _mapper.ProjectTo<StockInDto>(models).OrderBy(x => x.InTime).ToListAsync();
            //查询物料信息
            foreach (var dto in dtos)
            {
                var cargo = await _repository.GetCargoByIdAsync(dto.CargoId);
                if (cargo==null) continue;
                dto.MtlNumber = cargo.MtlNumber;
                dto.Description = cargo.Description;
                dto.Unit=cargo.Unit;
                dto.Location = cargo.Location;
                dto.Operator= (await _userService.GetSingleAsync(dto.OperatorId)).Result.UserName;
            }
            return new ApiResponse<IEnumerable<StockInDto>> { Status = true, Result = dtos };
        }
        catch (Exception e)
        {
            return new ApiResponse<IEnumerable<StockInDto>> { Status = false, Message = e.Message };
        }
    }

    public async Task<ApiResponse<IEnumerable<StockInDto>>> GetAllByPeriodAsync(DateTime start, DateTime end)
    {
        try
        {
            var models = await _repository.GetStockInsByPeriodAsync(start, end);
            //按照库位排序
            var dtos = await _mapper.ProjectTo<StockInDto>(models).OrderBy(x => x.InTime).ToListAsync();
            //查询物料信息
            foreach (var dto in dtos)
            {
                var cargo = await _repository.GetCargoByIdAsync(dto.CargoId);
                if (cargo==null) continue;
                dto.MtlNumber = cargo.MtlNumber;
                dto.Description = cargo.Description;
                dto.Unit=cargo.Unit;
                dto.Location = cargo.Location;
                dto.Operator= (await _userService.GetSingleAsync(dto.OperatorId)).Result.UserName;
            }
            return new ApiResponse<IEnumerable<StockInDto>> { Status = true, Result = dtos };
        }
        catch (Exception e)
        {
            return new ApiResponse<IEnumerable<StockInDto>> { Status = false, Message = e.Message };
        }
    }
    #endregion
}